package com.heima.search.service.Impl;

import com.alibaba.fastjson.JSON;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.utils.AppThreadLocalUtils;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.swing.text.Highlighter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ArticleSearchServiceImpl implements ArticleSearchService {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private ApUserSearchService apUserSearchService;

    /**
     * es文章分页检索
     * @param dto
     * @return
     * @throws IOException
     */
    @Override
    public ResponseResult search(UserSearchDto dto) throws IOException {

        //参数校验
        if (dto == null || StringUtils.isBlank(dto.getSearchWords())){
            ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        //异步调用保存搜索记录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user != null && dto.getFromIndex() == 0){
            apUserSearchService.insert(dto.getSearchWords(), user.getId());
        }

        SearchRequest request = new SearchRequest("app_info_article");

        SearchSourceBuilder source=request.source();

        BoolQueryBuilder boolQuery=QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.multiMatchQuery(dto.getSearchWords(),"title","content"));

        boolQuery.filter(QueryBuilders.rangeQuery("publishTime").lt(dto.getMinBehotTime()));
        //多条件查询
        source.query(boolQuery);
        //分页大小超出20 则设置20  分页处理
        if(dto.getPageSize() >20){
            dto.setPageSize(20);
            dto.setPageNum(dto.getPageNum()*dto.getPageSize());
        }
        //分页
        source.from(dto.getPageNum());
        source.size(dto.getPageSize());

        source.sort("publishTime", SortOrder.DESC);
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title").preTags("<font style='color: red; font-size: inherit;'>");
        highlightBuilder.postTags("</font>");
        source.highlighter(highlightBuilder);


        SearchResponse response=client.search(request, RequestOptions.DEFAULT);
        //处理响应结果
        SearchHits hits=response.getHits();
        List<Map> list = new ArrayList<>();

        for (SearchHit hit : hits.getHits()) {
            String json = hit.getSourceAsString();
            Map map = JSON.parseObject(json, Map.class);

            Map<String, HighlightField> highlightFields=hit.getHighlightFields();
            //判断是否包含高亮
            if(highlightFields != null && highlightFields.size() > 0){
                String title=highlightFields.get("title").getFragments()[0].string();
                if(StringUtils.isNotBlank(title)){
                    map.put("h_title",title);
                }
            }else {
                map.put("h_title",map.get("title"));
            }
            list.add(map);
        }

        return ResponseResult.okResult(list);
    }
}
